<?php


namespace App\Services;


use App\Enums\Field;
use App\Models\Library\ApprovedColorant;
use App\Models\Library\ApprovedPreservative;
use App\Models\Library\ApprovedSunScreen;
use App\Models\Library\ApprovedTint;
use App\Models\Library\DisableBioticComponent;
use App\Models\Library\DisableComponent;
use App\Models\Library\Inci;
use App\Models\Library\LimitedComponent;
use App\Models\Library\UsedMaterials;
use Illuminate\Support\Arr;
use Matchish\ScoutElasticSearch\MixedSearch;

class MaterialService extends BaseService
{
    public function getQueryCondition()
    {
        return Field::ruleEnum;
    }

    public function select(array $params)
    {
        $keywords = Arr::get($params, 'keywords');
        $range = Arr::get($params, 'range') ?? 'all';
        $rules = Arr::get($params, 'rules') ? json_decode(Arr::get($params, 'rules')) : array_keys(Field::ruleEnum);
        $modes = Arr::get($params, 'modes') ?? 'fuzzy_search';
//        $result = MixedSearch::search('name_en:' . $keywords . ' or name_zh:' . $keywords)
//            ->within(implode(',', [
//                (new ApprovedColorant())->searchableAs(),
//                (new ApprovedPreservative())->searchableAs(),
//                (new ApprovedSunScreen())->searchableAs(),
//                (new ApprovedTint())->searchableAs(),
//                (new DisableBioticComponent())->searchableAs(),
//                (new DisableComponent())->searchableAs(),
//                (new LimitedComponent())->searchableAs(),
//                (new UsedMaterials())->searchableAs(),
//            ]))
//            ->get()
//            ->toArray();
        $directories = $newMaterials = [];
        foreach (Field::MaterialEnum as $arr) {
            // 如果不在当前选择的法规清单中则不去处理
            if (!in_array($arr['key'], $rules)) continue;
            $data = $this->commonSearch($arr['class'], compact('keywords', 'range', 'modes'));
            if (!empty($data)) $directories[$arr['key']] = array_merge(
                Arr::only($arr, 'label'), [
                'data' => $data
            ]);
        }
        foreach (Field::newMaterialEnum as $newMaterialArr) {
            $data = $this->commonSearch($newMaterialArr['class'], compact('keywords', 'range', 'modes'));
            if (!empty($data)) $newMaterials[$newMaterialArr['key']] = array_merge(
                Arr::only($newMaterialArr, 'label'), [
                'data' => $data
            ]);
        }
        $results = [
            'directories' => $directories,
            'newMaterials' => $newMaterials
        ];

        return $results;
    }

    public function commonSearch($class, $data)
    {
        if (!$data['keywords']) {
            return app($class)->limit(10)->get()->toArray();
        } else {
            $query = $this->getQueryContent($data);
            return app($class)->search($query)->get()->toArray();
        }
    }

    public function getQueryContent(array $data)
    {
        switch ($data['range']) {
            case 'all':
                $query = 'cas:' . $data['keywords'] . ' or name_en:' . $data['keywords'] . ' or name_zh:' . $data['keywords'];
                break;
            case 'cas':
                $query = 'cas:' . $data['keywords'];
                break;
            case 'name_en':
                $query = 'name_en:' . $data['keywords'];
                break;
            case 'name_zh':
                $query = 'name_zh:' . $data['keywords'];
                break;
        }

        return $query;
    }

    public function getDetail(array $param)
    {
        $usedMaterial = $this->findByIdAndWith(
            (new UsedMaterials()),
            $param['id'],
            [
                'details',
//                'inci',
//                'approvedColorant',
//                'approvedPreservative',
//                'approvedSunScreen',
//                'approvedTint',
//                'disableBioticComponent',
//                'disableComponent',
//                'limitedComponents',
//                'riskMaterial'
            ],
            '已使用原料不存在！'
        );
        $limit = $preservative = $sunScreen = $colorant = $tint = [];
        foreach ($usedMaterial->details as $detail) {
            switch ($detail->type) {
                case 'limit':
                    $limit[] = $detail;
                    break;
                case 'preservative':
                    $preservative[] = $detail;
                    break;
                case 'sunScreen':
                    $sunScreen[] = $detail;
                    break;
                case 'colorant':
                    $colorant[] = $detail;
                    break;
                case 'tint':
                    $tint[] = $detail;
                    break;
            }
        }
        $usedMaterial->setAttribute('detail_limits', $limit);
        $usedMaterial->setAttribute('detail_preservatives', $preservative);
        $usedMaterial->setAttribute('detail_sun_screens', $sunScreen);
        $usedMaterial->setAttribute('detail_colorants', $colorant);
        $usedMaterial->setAttribute('detail_tints', $tint);
        unset($usedMaterial->details);

        return ['usedMaterial' => $usedMaterial];
    }
}
